package com.yuanfeng.payment.service.impl;

import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jfinal.kit.StrKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import com.yuanfeng.commoms.config.ALiPayConfig;
import com.yuanfeng.commoms.config.WXConfigUtil;
import com.yuanfeng.commoms.config.WXPayConfig;
import com.yuanfeng.commoms.config.YFConfig;
import com.yuanfeng.commoms.constant.CommonStatusEnum;
import com.yuanfeng.commoms.constant.CommonType;
import com.yuanfeng.commoms.dto.order.ConsumeRecordByBusinessDTO;
import com.yuanfeng.commoms.dto.order.ConsumeRecordParaDTO;
import com.yuanfeng.commoms.dto.order.RefundParamDTO;
import com.yuanfeng.commoms.dto.payment.AccountPeriodParamDTO;
import com.yuanfeng.commoms.dto.payment.GroupBookingParamDTO;
import com.yuanfeng.commoms.dto.payment.GroupBookingTradeDTO;
import com.yuanfeng.commoms.dto.payment.RefundAccountParamDTO;
import com.yuanfeng.commoms.dto.shop.ShopSalesStatisticsDTO;
import com.yuanfeng.commoms.exception.BizCodeEnume;
import com.yuanfeng.commoms.util.*;
import com.yuanfeng.commoms.util.excel.ExcelsUtil;
import com.yuanfeng.commoms.util.querypage.PageUtils;
import com.yuanfeng.commoms.util.querypage.Query;
import com.yuanfeng.commoms.vo.order.OrderBaseVO;
import com.yuanfeng.commoms.vo.payment.AccountShopBillDetailsVO;
import com.yuanfeng.commoms.vo.shop.AccountPeriodVO;
import com.yuanfeng.commoms.vo.user.UserInfoVO;
import com.yuanfeng.payment.dto.FinancialDetailsDTO;
import com.yuanfeng.payment.entity.PayConsumeRecordEntity;
import com.yuanfeng.payment.entity.PayConsumeTradeEntity;
import com.yuanfeng.payment.entity.PayConsumeWithdrawEntity;
import com.yuanfeng.payment.mapper.PayConsumeRecordMapper;
import com.yuanfeng.payment.mapper.PayConsumeTradeMapper;
import com.yuanfeng.payment.mapper.PayConsumeWithdrawMapper;
import com.yuanfeng.payment.mapper.PayUserResourceMapper;
import com.yuanfeng.payment.service.PayConsumeRecordService;
import com.yuanfeng.payment.vo.ComsumeRecordParaVO;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName PayConsumeRecordServiceImpl
 * @Description 交易明细表-账户收支明细-资金流水表-账户金额变化流水
 * @Author cyp
 * @Date 2023-05-31 15:36:55
 * @Version 1.0
 **/
@Service
public class PayConsumeRecordServiceImpl extends ServiceImpl<PayConsumeRecordMapper, PayConsumeRecordEntity>
        implements PayConsumeRecordService {

    @Autowired
    private PayConsumeTradeMapper payConsumeTradeMapper;

    @Autowired
    private PayConsumeWithdrawMapper payConsumeWithdrawMapper;

    @Autowired
    private PayUserResourceMapper payUserResourceMapper;

    @Override
    public boolean insertByBusiness(ConsumeRecordByBusinessDTO crb) {
        String sellerId = crb.getSellId();
        String userName = crb.getUserName();
        BigDecimal paymentAmout = crb.getTotalPrice();
        String tradeDate = DateUtils.getYear() + "-" + DateUtils.getMonth() + "-" + DateUtils.getDay();
        String tradeYear = DateUtils.getYear();
        String tradeMonth = DateUtils.getMonth();
        String tradeDay = DateUtils.getDay();
        String tradeTitle = "购物";
        List<String> goodsName = crb.getGoodsName();
        String tradeDesc = goodsName.get(0);
        String recordTime = DateUtils.getNowDateToString();
        Integer tradeTypeId = 1;
        Integer userType = 1;//1-收款方 2-付款方
        Integer recordStatus = 1;
        Integer isCurrentUser = 2;//判断当前订单是否属于当前用户 1 是 2 否
        String recordPayorderId = crb.getOrderId();// 实际单号
        String paymentNumber = crb.getPaymentNumber();// 支付号
        boolean isInsertSellerSuccess = this.baseMapper.insertConsumeRecordToSeller(paymentNumber, sellerId, userName,
                paymentAmout, tradeDate, tradeYear, tradeMonth, tradeDay, tradeTitle, tradeDesc, recordTime,
                tradeTypeId, userType, recordStatus, recordPayorderId,isCurrentUser);
        if (isInsertSellerSuccess) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean insertByBuyer(ConsumeRecordParaDTO crp) {
        String userId = crp.getUserId();
        String userName = crp.getUserName();
        BigDecimal paymentAmout = crp.getTotalPrice();
        String tradeDate = DateUtils.getYear() + "-" + DateUtils.getMonth() + "-" + DateUtils.getDay();
        String tradeYear = DateUtils.getYear();
        String tradeMonth = DateUtils.getMonth();
        String tradeDay = DateUtils.getDay();
        String tradeTitle = "购物";
        List<String> goodsName = crp.getGoodsName();
        String tradeDesc = goodsName.get(0);
        String recordTime = DateUtils.getNowDateToString();
        Integer tradeTypeId = 1;
        Integer userType = 2;//1-收款方 2-付款方
        Integer recordStatus = 1;
        Integer isCurrentUser = 1;//判断当前订单是否属于当前用户 1 是 2 否
        String recordPayorderId = crp.getOrderId();// 实际单号
        String paymentNumber = crp.getPaymentNumber();// 支付号
        boolean isInsertBuyerSuccess = this.baseMapper.insertBuyUserConsumeRecord(paymentNumber, userId, userName, paymentAmout,
                tradeDate, tradeYear, tradeMonth, tradeDay, tradeTitle, tradeDesc, recordTime, tradeTypeId, userType,
                recordStatus, recordPayorderId,isCurrentUser);
        if (isInsertBuyerSuccess) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public ResponseResult queryDealRecord(Map<Object, Object> map) {
        String token = (String) map.get("token");
        UserInfoVO ui = ParseTokenUtils.getUserInfoByToken(token);
        String userId = ui.getUserId();
        try {

            Integer tradeTypeId = (Integer) map.get("tradeTypeId");
            List<ComsumeRecordParaVO> comsumeRecordParaList = this.baseMapper.queryRecentDealRecord(userId, tradeTypeId);
            for(ComsumeRecordParaVO cp:comsumeRecordParaList){
                String orderId = cp.getRecordPayorder();
                if(5 != cp.getTradeTypeId()){
                    cp.setOrderRefundStatus(0);
                    cp.setOrderReturnStatus(0);
                }else{
                    String refundOrderNum = this.baseMapper.queryRefundOrderNum(orderId);//查询退单号
                    cp.setOrderId(refundOrderNum);

                }
            }
            return ResponseResult.success(comsumeRecordParaList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseResult.fail(BizCodeEnume.SYSTEM_ERROR.getCode(),BizCodeEnume.SYSTEM_ERROR.getMsg());
    }

    @Override
    public ResponseResult deleteDealRecord(Map<Object, Object> map) {
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(map.get("token").toString());
        if (null == userInfo) {
            return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID.getCode(),BizCodeEnume.TOKEN_IS_INVALID.getMsg());
        }
        Integer recordId = (Integer) map.get("recordId");
        this.baseMapper.updateRecordDelete(userInfo.getUserId(), recordId);
        return ResponseResult.success();
    }

    @Override
    public ResponseResult queryDealRecordDetails(Map<Object, Object> map) {
        return null;
    }

    @Override
    public ResponseResult updateCancelStatus(String orderId) {
        boolean isUpdateRecord = this.baseMapper.update(null, new LambdaUpdateWrapper<PayConsumeRecordEntity>()
                .eq(PayConsumeRecordEntity::getOrderId, orderId)
                .set(PayConsumeRecordEntity::getRecordStatus, CommonType.recordStatus.CANCEL.getCode())) == CommonStatusEnum.SUCCESS.getCode();
        boolean isUpdateTrade = payConsumeTradeMapper.update(null, new LambdaUpdateWrapper<PayConsumeTradeEntity>()
                .eq(PayConsumeTradeEntity::getOrderId, orderId)
                .set(PayConsumeTradeEntity::getOrderStateId, CommonType.recordStatus.CANCEL.getCode())) == CommonStatusEnum.SUCCESS.getCode();
        if (isUpdateRecord && isUpdateTrade) {
            return ResponseResult.success();
        } else {
            return ResponseResult.fail();
        }
    }

    @Override
    public ResponseResult change(String orderId) {
        boolean isUpdateRecord = this.baseMapper.update(null, new LambdaUpdateWrapper<PayConsumeRecordEntity>()
                .eq(PayConsumeRecordEntity::getRecordPayorder, orderId)
                .set(PayConsumeRecordEntity::getRecordStatus, CommonType.recordStatus.CONFIRM_RECEIPT.getCode())) == CommonStatusEnum.SUCCESS.getCode();
        boolean isUpdateTrade = payConsumeTradeMapper.update(null, new LambdaUpdateWrapper<PayConsumeTradeEntity>()
                .eq(PayConsumeTradeEntity::getOrderId, orderId)
                .set(PayConsumeTradeEntity::getOrderStateId, CommonType.recordStatus.CONFIRM_RECEIPT.getCode())) == CommonStatusEnum.SUCCESS.getCode();
        if (isUpdateRecord && isUpdateTrade) {
            return ResponseResult.success();
        } else {
            return ResponseResult.fail();
        }
    }

    @Override
    public ResponseResult insertRecord(Map<String, Map<String, String>> returnMap) {
        Map<String, String> userMap = returnMap.get("user");
        Map<String, String> sellerMap = returnMap.get("seller");
        Double money = Math.abs(Double.parseDouble(sellerMap.get("recordMoney")));
        //买家
        userMap.put("plusOrMinus", "1");
        //卖家
        sellerMap.put("plusOrMinus", "0");
        sellerMap.put("recordMoney", String.valueOf(money));
        Integer one = this.baseMapper.insertRecord(userMap);
        Integer two = this.baseMapper.insertRecord(sellerMap);
        if (!CommonType.commonStatus.YES.getCode().equals(one) || !CommonType.commonStatus.YES.getCode().equals(two)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.fail();
        }
        return ResponseResult.success();
    }

    @Override
    public void updateRefuse(Map<String, String> feignMap) {
        this.baseMapper.updateRecordRefuse(feignMap);
    }

    @Override
    public ResponseResult querySalesStatistics(ShopSalesStatisticsDTO param) {
        if (param.getStartTime() == "" && param.getEndTime() == "") {
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String finishTime = dateformat.format(new Date());
            Calendar c = Calendar.getInstance();
            // 过去1个月
            c.setTime(new Date());
            c.add(Calendar.MONTH, -1);
            Date m3 = c.getTime();
            String startTime = dateformat.format(m3);
            param.setEndTime(finishTime);
            param.setStartTime(startTime);

        }
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(param.getToken());
        if (null != userInfo) {
            IPage<ShopSalesStatisticsDTO> page = getStatistics(param);
            return ResponseResult.success(PageUtils.getPage(page));
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    public ResponseResult querySalesStatisticsExcel(ShopSalesStatisticsDTO param) {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(param.getToken());
        if (null != userInfo) {
            String[] title = {"店铺名称", "卡支付金额", "余额支付金额", "通联支付金额", "微信", "支付宝", "代金券", "红包", "运费",
                    "退款", "合计"};
            if (param.getStartTime() == "" && param.getEndTime() == "") {
                SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String finishTime = dateformat.format(new Date());
                Calendar c = Calendar.getInstance();
                // 过去1个月
                c.setTime(new Date());
                c.add(Calendar.MONTH, -1);
                Date m3 = c.getTime();
                String startTime = dateformat.format(m3);
                param.setEndTime(finishTime);
                param.setStartTime(startTime);
            }
            List<Map<String, String>> list = Lists.newArrayList();
            param.setLimit(6000);
            IPage<ShopSalesStatisticsDTO> page = getStatistics(param);
            List<ShopSalesStatisticsDTO> records = page.getRecords();
            for (ShopSalesStatisticsDTO res : records) {
                HashMap<String, String> map = com.google.common.collect.Maps.newHashMap();
                map.put("店铺名称", res.getShopName());
                map.put("卡支付金额", BigDecimal.valueOf(res.getCardPayment()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("余额支付金额", BigDecimal.valueOf(res.getBalancePayment()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("通联支付金额",
                        BigDecimal.valueOf(res.getCommunicationsPayment()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("微信", BigDecimal.valueOf(res.getWeChatOnePayment()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("支付宝", BigDecimal.valueOf(res.getAlipayPayment()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("代金券", BigDecimal.valueOf(res.getVoucherPrice()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("红包", BigDecimal.valueOf(res.getOrderRptPrice()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("运费", BigDecimal.valueOf(res.getShippingFee()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("退款", BigDecimal.valueOf(res.getRefundMoney()).setScale(2, RoundingMode.HALF_UP) + "");
                map.put("合计", res.getTotalPayment() + "");
                list.add(map);
            }
            // excel文件名
            //此处的key为每个sheet的名称，一个excel中可能有多个sheet页 此处key对应每一列的标题 该list为每个sheet页的数据
            Map<String/* 此处的key为每个sheet的名称，一个excel中可能有多个sheet页 */, List<Map<String/* 此处key对应每一列的标题 */, String>>/*
             * 该list为每个sheet页的数据
             */> map = Maps.newHashMap();
            map.put("店铺销售统计", list);
            //此处数组为需要合并的列，可能有的需求是只需要某些列里面相同内容合并
            String url = ExcelsUtil.createExcel(title, map, new int[]{0});

            return ResponseResult.success(url);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    public ResponseResult platformQueryDetails(FinancialDetailsDTO param) {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(param.getToken());
        if (null != userInfo) {
            try {
                Integer returnFlag = 0;
                if (LimitUtils.checkLimit("rechargeDetail", userInfo)) {
                    //将对象转换为map
                    Map data = ParseMapUtils.beanToMap(param);
                    //分页查询数据
                    IPage<PayConsumeRecordEntity> page = this.baseMapper.platformQueryDetails(new Query<PayConsumeRecordEntity>().getPage(data), param);
                    if(null != page.getRecords() && page.getRecords().size() > 0 ) {
                        for (PayConsumeRecordEntity entity : page.getRecords()) {
                            String orderId = entity.getRecordPayorder();
                            //通过是否R开头以区分充值单号和订单号
                            if (null != orderId && !orderId.startsWith("R") && !orderId.startsWith("W") && !orderId.startsWith("T")) {
                                //1-充值;2-提现;3-购物消费;4-转账;
                                entity.setDetailType(3);
                                OrderBaseVO orderInfoEntity = this.baseMapper.queryOrderInfo(orderId);
                                if (null == orderInfoEntity) {
                                    orderInfoEntity = new OrderBaseVO();
                                }
                                entity.setRecordPaytime(orderInfoEntity.getPaymentTime());
                                entity.setOrderStatus(orderInfoEntity.getOrderStatus());
                                Integer virtualGoods = orderInfoEntity.getVirtualGoods();
                                Integer orderIsShopTake = orderInfoEntity.getOrderIsShopTake();
                                if (null != orderIsShopTake && 1 == orderIsShopTake) {
                                    entity.setOrderType(3);
                                } else {
                                    if (null != virtualGoods && 0 == virtualGoods) {
                                        entity.setOrderType(2);
                                        entity.setPastDue(orderInfoEntity.getPastDue());
                                        entity.setIsCancel(orderInfoEntity.getIsCancel());
                                    } else {
                                        entity.setOrderType(1);
                                    }
                                }
                                Integer returnStatus = orderInfoEntity.getOrderReturnStatus() == null ?0:Integer.valueOf(orderInfoEntity.getOrderReturnStatus());
                                Integer refundStatus = orderInfoEntity.getOrderRefundStatus() == null ?0:Integer.valueOf(orderInfoEntity.getOrderRefundStatus());

                                entity.setReturnStatus(returnStatus);
                                entity.setRefundStatus(refundStatus);
                                if (2 == returnStatus || 2 == refundStatus) {
                                    BigDecimal returnAmount = new BigDecimal(orderInfoEntity.getOrderRefundAmount());
                                    BigDecimal orderAmount = orderInfoEntity.getOrderPaymentAmount();
                                    if (orderAmount.compareTo(returnAmount) > 0) {
                                        returnFlag = 2;
                                    } else if ((orderAmount.compareTo(returnAmount) == 0)) {
                                        returnFlag = 1;
                                    }
                                }
                                entity.setReturnFlag(returnFlag);
                            } else if (null != orderId && orderId.startsWith("R")) {
                                //1-充值;2-提现;3-购物消费;4-转账;
                                entity.setDetailType(1);
                                //充值成功
                                entity.setRecordStatus(1);
                            } else if (null != orderId && orderId.startsWith("W")) {
                                entity.setDetailType(2);
                                Integer start = payConsumeWithdrawMapper.selectOne(new LambdaQueryWrapper<PayConsumeWithdrawEntity>()
                                                .eq(PayConsumeWithdrawEntity::getOrderid,orderId)).getIsSucceed();
                                //0 待审核  2 打款完成 3 通过 4不通过
                                entity.setRecordStatus(start);
                            } else if (null != orderId && orderId.startsWith("T")) {
                                //1-充值;2-提现;3-购物消费;4-转账;
                                entity.setDetailType(4);
                            }
                        }
                    }
                    return ResponseResult.success(PageUtils.getPage(page));
                } else {
                    return ResponseResult.fail(BizCodeEnume.INSUFFICIENT_PERMISSIONS);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    public boolean insertSettlementRecord(Map<String, Object> map) {
        String token = (String) map.get("token");
        boolean flag = false;
        try {
            UserInfoVO ui = ParseTokenUtils.getUserInfoByToken(token);
            if (ui == null) {
                return flag;
            }
            String userId = ui.getUserId();
            String userName = ui.getUserName();
            // 结算编号
            String settlementId = (String) map.get("settlementId");
            // 结算金额
            String settlementMoney = (String) map.get("settlementMoney");
            Integer settlementType = null == map.get("settlementType") ? 1 : Integer.parseInt(map.get("settlementType") + "");
            BigDecimal money = new BigDecimal(settlementMoney);
            String recordDate = DateUtils.getYear() + "-" + DateUtils.getMonth() + "-" + DateUtils.getDay();
            String recordYear = DateUtils.getYear();
            String recordMonth = DateUtils.getMonth();
            String recordDay = DateUtils.getDay();
            String recordTitle = "商家结算";
            String recordDesc = "结算";
            String recordTime = DateUtils.getTime();
            Integer tradeTypeId = 11;
            Integer userType = 1;
            Integer recordStatus = 6;
            String recordPayorder = settlementId;
            Integer plusOrMinus = null;
            boolean isUpdateUserMoney = false;
            BigDecimal judge = new BigDecimal(0);
            if (money.compareTo(judge) < 0) {
                settlementMoney = settlementMoney.substring(1);
                plusOrMinus = 0;
                // 账户余额
                BigDecimal userMoney = payUserResourceMapper.queryUserMoney(userId);
                // 提现金额
                BigDecimal withdrawalMoney = new BigDecimal(settlementMoney);
                if (userMoney.compareTo(withdrawalMoney) < 0) {
                    return false;
                } else {
                    isUpdateUserMoney = payUserResourceMapper.updateMinusUserMoney(userId, settlementMoney);
                }
            } else {
                plusOrMinus = 1;
                isUpdateUserMoney = payUserResourceMapper.updateUserMoney(userId, money);
            }
            if (isUpdateUserMoney) {
                Map<String, Object> mapRecord = new HashMap<>();
                mapRecord.put("settlementId", settlementId);
                mapRecord.put("settlementType", settlementType);
                mapRecord.put("userId", userId);
                mapRecord.put("userName", userName);
                mapRecord.put("settlementMoney", settlementMoney);
                mapRecord.put("recordDate", recordDate);
                mapRecord.put("recordYear", recordYear);
                mapRecord.put("recordMonth", recordMonth);
                mapRecord.put("recordDay", recordDay);
                mapRecord.put("recordTitle", recordTitle);
                mapRecord.put("recordDesc", recordDesc);
                mapRecord.put("recordTime", recordTime);
                mapRecord.put("tradeTypeId", tradeTypeId);
                mapRecord.put("userType", userType);
                mapRecord.put("recordStatus", recordStatus);
                mapRecord.put("recordPayorder", recordPayorder);
                mapRecord.put("plusOrMinus", plusOrMinus);
                boolean isInsertSuccess = this.baseMapper.insertSettlementRecord(mapRecord);
                if (isInsertSuccess) {
                    flag = true;
                }
            }
        } catch (Exception e) {
            System.err.println(e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return flag;
    }

    @Override
    public ResponseResult recentTransactionOrder(Map<String, Object> map) {
        String token = (String) map.get("token");
        Integer returnFlag = 0;
        boolean isExist = RedisUtil.exists(YFConfig.YF_USER_TOKEN_USER + token);
        if (isExist) {
            String userId = RedisUtil.get(YFConfig.YF_USER_TOKEN_USERID + token);
            try {
                IPage<PayConsumeRecordEntity> spct = this.page(new Query<PayConsumeRecordEntity>().getPage(map),
                        new LambdaQueryWrapper<PayConsumeRecordEntity>().eq(PayConsumeRecordEntity::getUserId, userId)
                                                                        .between(PayConsumeRecordEntity::getUserType,1,2)
                                                                        .orderByDesc(PayConsumeRecordEntity::getRecordTime));
                if (spct.getRecords() == null) {
                    return ResponseResult.success(BizCodeEnume.ORDER_IS_NULL);
                }

                for (PayConsumeRecordEntity financialDetail : spct.getRecords()) {
                    String recordPayorder = financialDetail.getOrderId();
                    //通过是否R开头以区分充值单号和订单号
                    if (null != recordPayorder && !recordPayorder.startsWith("R") && !recordPayorder.startsWith("W") && !recordPayorder.startsWith("T")) {
                        //1-充值;2-提现;3-购物消费;4-转账;
                        financialDetail.setDetailType(3);
                        OrderBaseVO orderInfoEntity = this.baseMapper.queryOrderInfo(financialDetail.getRecordPayorder());
                        if (null == orderInfoEntity) {
                            orderInfoEntity = new OrderBaseVO();
                        }
                        financialDetail.setOrderStatus(orderInfoEntity.getOrderStatus());
                        Integer virtualGoods = orderInfoEntity.getVirtualGoods();
                        Integer orderIsShopTake = orderInfoEntity.getOrderIsShopTake();
                        if (null != orderIsShopTake && 1 == orderIsShopTake) {
                            financialDetail.setOrderType(3);
                        }
                        if (null != virtualGoods && 0 == virtualGoods) {
                            financialDetail.setOrderType(2);
                            financialDetail.setPastDue(orderInfoEntity.getPastDue());
                            financialDetail.setIsCancel(orderInfoEntity.getIsCancel());
                        } else {
                            financialDetail.setOrderType(1);
                        }
                        Integer returnStatus = orderInfoEntity.getOrderReturnStatus() != null ? Integer.valueOf(orderInfoEntity.getOrderReturnStatus()) : null;
                        Integer refundStatus = orderInfoEntity.getOrderRefundStatus() != null ? Integer.valueOf(orderInfoEntity.getOrderRefundStatus()) : null;
                        if (null == returnStatus) {
                            returnStatus = 0;
                        }
                        if (null == refundStatus) {
                            refundStatus = 0;
                        }

                        financialDetail.setReturnStatus(returnStatus);
                        financialDetail.setRefundStatus(refundStatus);
                        if (2 == returnStatus || 2 == refundStatus) {
                            BigDecimal returnAmount = BigDecimal.valueOf(orderInfoEntity.getOrderRefundAmount());
                            BigDecimal orderAmount = orderInfoEntity.getOrderPaymentAmount();
                            if (orderAmount.compareTo(returnAmount) > 0) {
                                returnFlag = 2;
                            } else if ((orderAmount.compareTo(returnAmount) == 0)) {
                                returnFlag = 1;
                            }
                        }
                        financialDetail.setReturnFlag(returnFlag);
                    } else if (null != recordPayorder && recordPayorder.startsWith("R")) {
                        //1-充值;2-提现;3-购物消费;4-转账;
                        financialDetail.setDetailType(1);
                        //充值成功
                        financialDetail.setRecordStatus(1);
                    } else if (null != recordPayorder && recordPayorder.startsWith("W")) {
                        financialDetail.setDetailType(2);
                        Integer start = payConsumeWithdrawMapper.selectOne(new LambdaQueryWrapper<PayConsumeWithdrawEntity>()
                                        .eq(PayConsumeWithdrawEntity::getOrderid,recordPayorder)).getIsSucceed();
                        //0 待审核  2 打款完成 3 通过 4不通过
                        financialDetail.setRecordStatus(start);
                    } else if (null != recordPayorder && recordPayorder.startsWith("T")) {
                        //1-充值;2-提现;3-购物消费;4-转账;
                        financialDetail.setDetailType(4);
                    }
                    BigDecimal recordMoney = new BigDecimal(financialDetail.getRecordMoney()).setScale(2, RoundingMode.HALF_UP);
                    String money = recordMoney.toString();
                    financialDetail.setMoney(money);
                }
                return ResponseResult.success(PageUtils.getPage(spct));
            } catch (Exception e) {
                e.printStackTrace();
                return ResponseResult.fail(2, e.getMessage());
            }
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
    }

    @Override
    public boolean waitShipmentsRefund(RefundParamDTO refundPara) {
        //查询支付配置信息
        selectYFPayConfig();
        System.out.println("======进入待发货退款=====");
        boolean flag = false;
        String orderId = refundPara.getOrderId();
        String refundOrderId = refundPara.getReturnCode();
        Integer payCode = refundPara.getPayCode();
        Integer orderFrom = refundPara.getOrderFrom();
        String paymentOtherNumber = refundPara.getPaymentOtherNumber();
        List<GroupBookingParamDTO> gbpList = this.baseMapper.queryRefundConsumeRecordMoney(orderId);// 退款共用

        String userId = null;
        String uOrderId = null;
        BigDecimal money = gbpList.get(0).getRecordMoney();
        // 退款金额
        BigDecimal allMoney = BigDecimal.ZERO;// 总金额
        BigDecimal AllTradePaymentRechargeCard = BigDecimal.ZERO;

        for (int i = 0; i < gbpList.size(); i++) {
            Integer type = 1;
            Integer userType = 3;
            if (userType.intValue() == gbpList.get(i).getUserType()) {
                // 当userType为 3 时，此订单为合并支付
                userId = gbpList.get(i).getUserId();
                uOrderId = gbpList.get(i).getOrderId();// 合并支付订单号
                allMoney = gbpList.get(i).getRecordMoney();// 合并支付总金额
            } else if (type.intValue() == gbpList.get(i).getUserType()) {
                // 其他情况，正常取值
                userId = gbpList.get(i).getUserId();
                uOrderId = gbpList.get(i).getOrderId();
                allMoney = this.baseMapper.calculateAllOrderMoney(uOrderId);// 计算订单总金额
                AllTradePaymentRechargeCard = this.baseMapper.queryAllTradePaymentRechargeCard(uOrderId);
            }
        }
        if(null == allMoney){
            allMoney = BigDecimal.ZERO;
        }
        if(null == AllTradePaymentRechargeCard){
            AllTradePaymentRechargeCard = BigDecimal.ZERO;
        }
        BigDecimal rechargeCardMoney = BigDecimal.ZERO;
        String tradeThirdPartyAmount = "";
        GroupBookingTradeDTO groupBookingTrade = this.baseMapper.queryRefundTrade(orderId);// 退款共用
        if(null != groupBookingTrade) {
            rechargeCardMoney = groupBookingTrade.getTradePaymentRechargeCard();// 获取充值卡金额
            tradeThirdPartyAmount = groupBookingTrade.getTradeThirdPartyAmount().toString();// 第三方付款金额
        }
        double tradeThirdPartyA = 0.00;
        if(org.apache.commons.lang.StringUtils.isNotEmpty(tradeThirdPartyAmount)) {
            tradeThirdPartyA = Double.parseDouble(tradeThirdPartyAmount);
        }
        double tradeThirdPartyB = 0.01;
        BigDecimal weChatTotalFee = allMoney.subtract(AllTradePaymentRechargeCard);
        List<Integer> orderTradeStatus = refundPara.getOrderTradeStatus();
        Set<Integer> set = new HashSet<Integer>(orderTradeStatus);

        if (payCode == 1) {
            // 账户余额
            flag = this.baseMapper.updateUserMoneyResource(userId, money);
        } else if (payCode == 9) {
            // 蜂卡
            flag = this.baseMapper.updateBeeCoinMoney(money, userId);
        } else if (payCode == 10) {
            // 蜂卡+支付宝

        } else if (payCode == 11) {

            // 组合(充值+微信)
        }else if (payCode == 2) {
            // 支付宝
            flag = aliPayRefund(paymentOtherNumber, money);
        } else if (payCode == 3) {
            // 微信
            flag = weChatRefund(paymentOtherNumber, refundOrderId, allMoney, money, orderFrom);
        } else if (payCode == 6) {
            // 充值卡
            flag = this.baseMapper.updateUserRechargeCardMoneyResource(userId, money);
        } else if (payCode == 7) {
            // 组合(充值+支付宝)

        } else if (payCode == 8) {
            // 组合(充值+微信)

        }else if (payCode == 12) {
            //线下付款
            flag = true;

        } else if (payCode == 13) {
            //账期付款
            String accountingPeriodId = this.baseMapper.queryAccountingPeriodId(orderId);
            RefundAccountParamDTO refundAccountParam = new RefundAccountParamDTO();
            refundAccountParam.setAccountingPeriodId(accountingPeriodId);
            refundAccountParam.setRefundPrice(money);
            flag = updateRefundAccountPeriod(refundAccountParam);
        } else if (payCode == 14) {
            // 账户余额
            flag = this.baseMapper.updateUserMoneyResource(userId, money);
        } else if (payCode == 15) {
            // 购物卡
            flag = this.baseMapper.updateUserRechargeCardMoneyResource(userId, money);
        }

        if (flag) {
            this.baseMapper.updateOrderRefund(orderId);// 更新record退款状态
            this.baseMapper.updateOrderTrade(orderId);// 更新trade退款状态
            this.baseMapper.updateReturnCash(refundPara);//自营联盟
            this.baseMapper.updateDistributorReturn(refundPara);//分销商
        }
        return flag;
    }

    public static String postSSL(String url, String data, String certPath, String certPass) {
        String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";
        HttpsURLConnection conn = null;
        OutputStream out = null;
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            KeyStore clientStore = KeyStore.getInstance("PKCS12");
            clientStore.load(new FileInputStream(certPath), certPass.toCharArray());
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(clientStore, certPass.toCharArray());
            KeyManager[] kms = kmf.getKeyManagers();
            SSLContext sslContext = SSLContext.getInstance("TLS");

            sslContext.init(kms, null, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            URL _url = new URL(url);
            conn = (HttpsURLConnection) _url.openConnection();

            conn.setConnectTimeout(25000);
            conn.setReadTimeout(25000);
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setDoInput(true);

            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            conn.setRequestProperty("User-Agent", DEFAULT_USER_AGENT);
            conn.connect();
            out = conn.getOutputStream();
            out.write(data.getBytes(Charset.forName("UTF-8")));
            out.flush();
            inputStream = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream,Charset.forName("UTF-8")));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null){
                sb.append(line).append("\n");
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            IOUtils.closeQuietly(out);
            IOUtils.closeQuietly(reader);
            IOUtils.closeQuietly(inputStream);
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    public static boolean weChatRefund(String paymentOtherNumber, String refundOrderId, BigDecimal allMoney,
                                       BigDecimal money, Integer orderFrom) {
        boolean flag = false;
        System.out.println("-----uOrderId-----" + paymentOtherNumber);
        if (orderFrom == 2) {
            // 订单来自wap端
            Map<String, String> params = new HashMap<String, String>();
            params.put("appid", WXPayConfig.APP_ID);
            params.put("mch_id", WXPayConfig.MCH_ID);
            params.put("nonce_str", PayToolUtil.create_nonce_str());
            params.put("transaction_id", paymentOtherNumber);
            params.put("out_refund_no", refundOrderId);
            params.put("total_fee", PayToolUtil.getMoney(allMoney.toString()));
            params.put("refund_fee", PayToolUtil.getMoney(money.toString()));
            String sign = PaymentKit.createSign(params, WXPayConfig.API_KEY);
            params.put("sign", sign);

            System.out.println("abcd = weixin chat wap path = " + WXPayConfig.weChatWapPath);
            File file = new File(WXPayConfig.weChatWapPath);
            String xmlResult = postSSL(WXPayConfig.REFUND_URL,PaymentKit.toXml(params),WXPayConfig.weChatWapPath,WXPayConfig.MCH_ID);
            System.out.println(xmlResult);
            Map<String, String> result = PaymentKit.xmlToMap(xmlResult);

            String return_code = result.get("return_code");
            String return_msg = result.get("return_msg");
            if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
            }
            String result_code = result.get("result_code");
            if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
            } else {
                flag = true;
            }
        } else if (orderFrom == 6) {
            System.out.println("-----进入小程序判断-----");
            Map<String, String> params = new HashMap<String, String>();
            params.put("appid", WXPayConfig.Applet_APP_ID);
            params.put("mch_id", WXPayConfig.MCH_ID);
            params.put("nonce_str", PayToolUtil.create_nonce_str());
            params.put("transaction_id", paymentOtherNumber);
            params.put("out_refund_no", refundOrderId);
            params.put("total_fee", PayToolUtil.getMoney(allMoney.toString()));
            params.put("refund_fee", PayToolUtil.getMoney(money.toString()));
            String sign = PaymentKit.createSign(params, WXPayConfig.API_KEY);
            params.put("sign", sign);

            File file = new File(WXPayConfig.weChatWapPath);

            String xmlResult = postSSL(WXPayConfig.REFUND_URL,PaymentKit.toXml(params),WXPayConfig.weChatWapPath,WXPayConfig.MCH_ID);
            System.out.println(xmlResult);

            Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
            String return_code = result.get("return_code");
            String return_msg = result.get("return_msg");
            if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
            }
            String result_code = result.get("result_code");
            if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
            } else {
                flag = true;
            }
        } else {

            // 其他端
            Map<String, String> params = new HashMap<String, String>();
            params.put("appid", WXPayConfig.APP_ID);
            params.put("mch_id", WXPayConfig.MCH_ID);
            params.put("nonce_str", PayToolUtil.create_nonce_str());
            params.put("transaction_id", paymentOtherNumber);
            params.put("out_refund_no", refundOrderId);
            params.put("total_fee", PayToolUtil.getMoney(allMoney.toString()));
            params.put("refund_fee", PayToolUtil.getMoney(money.toString()));
            String sign = PaymentKit.createSign(params, WXPayConfig.API_KEY);
            params.put("sign", sign);

            File file = new File(WXPayConfig.weChatWapPath);
            if(file.exists()) {
            }
            String xmlResult = "";
            try{
                FileInputStream fileInputStream = new FileInputStream(WXPayConfig.weChatWapPath);
                System.out.println(WXPayConfig.REFUND_URL);
                System.out.println(PaymentKit.toXml(params));
                System.out.println(WXPayConfig.weChatWapPath);
                System.out.println(WXPayConfig.MCH_ID);
                xmlResult = postSSL(WXPayConfig.REFUND_URL,PaymentKit.toXml(params),WXPayConfig.weChatWapPath,WXPayConfig.MCH_ID);
                System.out.println(xmlResult);
            }catch (Exception e){}

            Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
            String return_code = result.get("return_code");
            String return_msg = result.get("return_msg");
            if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
            }
            String result_code = result.get("result_code");
            if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
            } else {
                flag = true;
            }
        }
        return flag;
    }

    public static boolean aliPayRefund(String paymentOtherNumber, BigDecimal money) {
        boolean flag = false;
        try {
            // SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签
            CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
            // 支付宝网关
            certAlipayRequest.setServerUrl(ALiPayConfig.URL);
            // 应用id
            certAlipayRequest.setAppId(ALiPayConfig.APPID);
            // 应用私钥路径
            certAlipayRequest.setPrivateKey(ALiPayConfig.RSA_PRIVATE_KEY);
            // 应用公钥路径
            certAlipayRequest.setCertPath(ALiPayConfig.ALIPAY_PUBLIC_CERT_PATH);
            // 支付宝应用公钥证书路径
            certAlipayRequest.setAlipayPublicCertPath(ALiPayConfig.CERT_PATH);
            // 支付宝证书，根证书路径
            certAlipayRequest.setRootCertPath(ALiPayConfig.ROOT_CERT_PATH);
            //设置签名
            certAlipayRequest.setSignType(ALiPayConfig.SIGNTYPE);
            // 设置签名类型
            certAlipayRequest.setFormat(ALiPayConfig.FORMAT);
            // 设置编码
            certAlipayRequest.setCharset(ALiPayConfig.CHARSET);
            // 调用RSA签名方式
            AlipayClient client = new DefaultAlipayClient(certAlipayRequest);
            // 设置请求参数
            AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
            refundModel.setTradeNo(paymentOtherNumber);
            refundModel.setRefundAmount(money.toString());
            refundModel.setRefundReason("超时退款");
            refundModel.setOutRequestNo("FR" + TimeStampUtil.nowtime() + TimeStampUtil.randomLengthByTwo() + "001");
            // 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            request.setBizModel(refundModel);

            AlipayTradeRefundResponse response = client.certificateExecute(request);
            if (response.isSuccess()) {
                flag = true;
            } else {
                flag = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    public Boolean updateRefundAccountPeriod(RefundAccountParamDTO param) {
        //退回账期可用额度
        int row = this.baseMapper.updateRefundAccountPeriod(param);
        if (row <= 0) {
            return false;
        }
        //查找账单信息
        AccountShopBillDetailsVO detail = this.baseMapper.selectDetailsByPeriodId(param.getAccountingPeriodId());
        //更改账单状态
        if (detail.getRemainingAccounts().compareTo(BigDecimal.ZERO) == 0) {
            //全部还款
            this.baseMapper.editAccountStatus(param.getAccountingPeriodId(), 2);
        } else if (detail.getRemainingAccounts().compareTo(BigDecimal.ZERO) == 1 && detail.getAccountStatus() != 3) {
            //部分还款且不逾期
            this.baseMapper.editAccountStatus(param.getAccountingPeriodId(), 1);
        }
        //修改账期会员的使用额度跟可用额度
        //查找账期会员的账期信息
        AccountPeriodVO account = this.baseMapper.getAccountPeriodByIds(detail.getShopId(), detail.getUserId());
        BigDecimal amountUsed = account.getAmountUsed().subtract(param.getRefundPrice());
        BigDecimal availableAmount = BigDecimal.ZERO;
        if (account.getAccountIsLimit() != 0) {
            availableAmount = account.getAvailableAmount().add(param.getRefundPrice());
        }
        BigDecimal monthAmountUsed = account.getMonthAmountUsed();
        Boolean isMonth = DateUtils.isMonth(new Date(), detail.getStartTime());
        if (isMonth) {
            monthAmountUsed = account.getMonthAmountUsed().subtract(param.getRefundPrice());
        }
        AccountPeriodParamDTO periodParam = new AccountPeriodParamDTO(detail.getShopId(), detail.getUserId(), amountUsed, availableAmount, monthAmountUsed);
        //更新账期信息
        this.baseMapper.updateAccountPeriod(periodParam);
        return true;
    }


    public void selectYFPayConfig() {

        String paymentMode = "00";//微信 pc  h5
        Map<String, String> outMap = this.baseMapper.selectYfPayConfig(paymentMode);
        WXPayConfig.API_KEY=outMap.get("appAPIKey").toString();
        WXPayConfig.APP_SECRET=outMap.get("appSecret").toString();
        WXPayConfig.MCH_ID=outMap.get("appMCHId").toString();
        WXPayConfig.APP_ID=outMap.get("appID").toString();
        WXPayConfig.NOTIFY_URL=outMap.get("notifyUrl").toString();
        WXPayConfig.REDIRECT_URL=outMap.get("redirectUrl").toString();
        WXPayConfig.weChatWapPath=outMap.get("weChatPcPath").toString();

        //微信app
        WXConfigUtil.KEY=outMap.get("appAPIKey").toString();
        WXConfigUtil.APP_SECRET=outMap.get("appSecret").toString();
        WXConfigUtil.MCH_ID=outMap.get("appMCHId").toString();
        WXConfigUtil.APP_ID=outMap.get("appID").toString();
        WXConfigUtil.NOTIFY_URL_APP= outMap.get("notifyUrl").toString();

        String paymentMode2 = "02";//微信小程序
        Map<String, String> outMap2 = this.baseMapper.selectYfPayConfig(paymentMode2);
        WXPayConfig.Applet_APP_ID=outMap2.get("appID").toString();
        WXPayConfig.Applet_APP_SECRET= outMap2.get("appSecret").toString();


        String paymentMode3 = "03";//支付宝
        outMap = this.baseMapper.selectYfPayConfig(paymentMode3);
        if(null != outMap && !outMap.isEmpty()) {
            ALiPayConfig.URL = outMap.get("gatewayURL").toString();
            ALiPayConfig.APPID = outMap.get("appID").toString();
            ALiPayConfig.sellerId = outMap.get("appMCHId").toString();
            ALiPayConfig.RSA_PRIVATE_KEY = outMap.get("appAPIKey").toString();
            ALiPayConfig.CERT_PATH = outMap.get("cert_public_key_res2").toString();
            ALiPayConfig.ROOT_CERT_PATH = outMap.get("cert_root_key").toString();
            ALiPayConfig.ALIPAY_PUBLIC_CERT_PATH = outMap.get("cert_app_public_key").toString();
            ALiPayConfig.shopping_notify_url = outMap.get("shoppingNotifyUrl").toString();
            ALiPayConfig.shopping_notify_url_h5 = outMap.get("rechargeNotifyUrl2").toString();
            ALiPayConfig.shopping_return_url_pc = outMap.get("shoppingReturnUrlPc").toString();
        }
    }
    private IPage<ShopSalesStatisticsDTO> getStatistics(ShopSalesStatisticsDTO param) {
        try {
            //将对象转换为map
            Map data = ParseMapUtils.beanToMap(param);
            //分页查询数据
            IPage<ShopSalesStatisticsDTO> page = this.baseMapper.querySalesStatistics(new Query<ShopSalesStatisticsDTO>().getPage(data), param);
            List<ShopSalesStatisticsDTO> records = page.getRecords();
            for (ShopSalesStatisticsDTO pojo : records) {
                BigDecimal totalPayment = BigDecimal.ZERO;
                BigDecimal cardPayment = BigDecimal.valueOf(pojo.getCardPayment());
                BigDecimal balancePayment = BigDecimal.valueOf(pojo.getBalancePayment());
                BigDecimal alipayPayment = BigDecimal.valueOf(pojo.getAlipayPayment());
                BigDecimal weChatPayment = BigDecimal.valueOf(pojo.getWeChatTwoPayment());
                BigDecimal orderRptPrice = BigDecimal.valueOf(pojo.getOrderRptPrice());
                totalPayment = totalPayment.add(cardPayment).add(balancePayment).add(alipayPayment).add(weChatPayment).add(orderRptPrice);
                totalPayment = totalPayment.setScale(2, RoundingMode.HALF_UP);
                //查询店铺退款信息
                BigDecimal returnCash = this.baseMapper.querShopReturnCash(pojo.getShopId(),param);
                if(null == returnCash){
                    returnCash = new BigDecimal(0);
                }
                pojo.setRefundMoney(returnCash.doubleValue());
                pojo.setTotalPayment(totalPayment.doubleValue());
            }
            page.setRecords(records);
            return page;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}
